package com.small.flowable.modules.app.controllers;

import com.alibaba.nacos.api.utils.StringUtils;
import com.common.basis.entity.BaseParam;
import com.common.basis.oauth.AuUser;
import com.common.basis.result.Result;
import com.common.basis.result.ResultPage;
import com.common.basis.result.ResultSet;
import com.small.flowable.modules.app.dao.entities.HistoryTask;
import com.small.flowable.modules.app.dto.rsp.ProcessInstanceRsp;
import com.small.flowable.modules.app.services.ProcessInstanceService;
import com.small.flowable.modules.modeler.services.MyRemoteService;
import lombok.AllArgsConstructor;
import org.flowable.engine.HistoryService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricDetail;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.identitylink.api.IdentityLinkType;
import org.flowable.identitylink.api.history.HistoricIdentityLink;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntityImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * 历史查询
 *
 * @author wangguochao
 */
@RestController
@AllArgsConstructor
@RequestMapping("history")
public class HistoryController {
    private final HistoryService historyService;
    private final ProcessInstanceService processInstanceService;
    private final TaskService taskService;
    private final MyRemoteService myRemoteService;

    /**
     * 历史实例
     */
    @GetMapping
    public ResultPage<HistoricProcessInstance> findAll(BaseParam<?> param) {
        int min = param.getMin();
        List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
                .orderByProcessInstanceEndTime().desc()
                .listPage(min, param.getSize());
        long count = historyService.createHistoricProcessInstanceQuery()
                .count();
        return ResultSet.page(list, count);
    }

    /**
     * 获取按任务ID列出的历史记录
     *
     * @param taskId 任务ID
     */
    @GetMapping("detail/list")
    public Result<List<HistoricDetail>> getHistoryListByTaskId(@RequestParam String taskId) {
        List<HistoricDetail> list = historyService.createHistoricDetailQuery()
                .formProperties()
                .taskId(taskId)
                .orderByVariableName().asc()
                .list();
        return ResultSet.go(list);
    }

    /**
     * 通过流程实例ID获取历史记录列表
     *
     * @param processInstanceId 实例ID
     */
    @GetMapping("getHistoryListByProcessInstanceId")
    public Result<ProcessInstanceRsp> getHistoryListByProcessInstanceId(@RequestParam String processInstanceId) {
        ProcessInstanceRsp processInstanceRsp = processInstanceService.getByProcessInstanceId(processInstanceId);
        List<HistoricDetail> list = historyService.createHistoricDetailQuery()
                .processInstanceId(processInstanceId)
                .excludeTaskDetails()
                .list();
        processInstanceRsp.setFromList(list);
        return ResultSet.go(processInstanceRsp);
    }

    /**
     * 历史节点
     *
     * @param taskDefinitionKey 节点标示
     * @param processInstanceId 实例ID
     * @return
     */
    @GetMapping("task")
    public Result<HistoricTaskInstanceEntityImpl> task(@RequestParam String taskDefinitionKey,
                                                       @RequestParam String processInstanceId) {
        HistoryTask historyTask = new HistoryTask();
        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId)
                .taskDefinitionKey(taskDefinitionKey)
                .orderByHistoricTaskInstanceEndTime().desc()
                .listPage(0, 1);
        if (historicTaskInstances.isEmpty()) {
            return ResultSet.go(historyTask);
        }
        HistoricTaskInstance historicTaskInstance = historicTaskInstances.get(0);
        List<HistoricIdentityLink> historicIdentityLinksForTask = historyService.getHistoricIdentityLinksForTask(historicTaskInstance.getId());
        //获取接口带出来带候选人与候选组信息
        List<String> originalCandidateUsers = new ArrayList<>();
        List<String> originalCandidateGroups = new ArrayList<>();
        for (HistoricIdentityLink identityLink : historicIdentityLinksForTask) {
            if (!IdentityLinkType.CANDIDATE.equalsIgnoreCase(identityLink.getType())) {
                continue;
            }
            //不存在候选信息则同步添加
            if (!StringUtils.isEmpty(identityLink.getUserId()) && !originalCandidateUsers.contains(identityLink.getUserId())) {
                originalCandidateUsers.add(identityLink.getUserId());
            } else if (!StringUtils.isEmpty(identityLink.getGroupId()) && !originalCandidateGroups.contains(identityLink.getGroupId())) {
                originalCandidateGroups.add(identityLink.getGroupId());
            }
        }
        if (!originalCandidateUsers.isEmpty()) {
            Result<List<AuUser>> byIds = myRemoteService.findByIds(originalCandidateUsers);
            if (byIds.getStatus() == 200) {
                List<AuUser> data = byIds.getData();
                historyTask.setUserList(data);
            }
        }
        List<HistoricDetail> list = historyService.createHistoricDetailQuery()
                .taskId(historicTaskInstance.getId())
                .formProperties()
                .orderByVariableName().asc()
                .list();
        BeanUtils.copyProperties(historicTaskInstance, historyTask);
        historyTask.setFromList(list);
        List<Comment> taskComments = taskService.getTaskComments(historicTaskInstance.getId());
        historyTask.setTaskComments(taskComments);
        return ResultSet.go(historyTask);
    }

}
